import { Card, Flex, List, Pagination } from 'antd';
import { SPACE } from '@/constants/themeConstant.js';
import styled from 'styled-components';
import { forwardRef, useEffect, useImperativeHandle, useMemo, useState } from 'react';
import { CheckCircleOutlined } from '@ant-design/icons';
import { useUpdateEffect } from 'ahooks';

const ListView = styled(List)`
  .ant-col:has(.card-list-item) {
    height: 100%;
  }
`;

const MultipleIcon = styled.div`
  position: absolute;
  top: 4px;
  right: 8px;
  font-size: 20px;

  &:hover {
    cursor: pointer;
    color: var(${'--ant-color-primary'});
  }

  ${(props) => (props?.selected === true ? 'color: var(--ant-color-primary);' : '')};
`;

/**
 * 卡片列表组件
 *
 * @param {object} props 属性
 * @param {string} rowKey 数据唯一标识
 * @param {object} props.pagination 分页器配置
 * @param {number} props.column 列表每行显示的列数
 * @param {function} props.renderItem 列表项渲染函数
 * @param {boolean} props.hoverable 卡片是否可悬停
 * @param {function} props.onClickCard 点击卡片的回调函数
 * @param {object} props.grid 卡片列表的布局配置
 * @param {function} props.request 请求数据的方法
 * @param {boolean} props.multiple 启用多选
 * @param {function} props.onSelectedRowsChange 多选状态改变的回调函数
 * @param {function} props.addCardBox 新增卡片的包裹盒子
 */
const CardList = forwardRef((props, ref) => {
  useImperativeHandle(ref, () => ({
    request,
    setSelectedRows,
    setPageNo
  }));

  const [total, setTotal] = useState(0);
  const [dataList, setDataList] = useState([]);
  const [loading, setLoading] = useState(false);
  const [pageSize, setPageSize] = useState(props?.pagination?.pageSize || 10);
  const [pageNo, setPageNo] = useState(1);
  const [selectedRows, setSelectedRows] = useState([]);

  useEffect(() => {
    request();
  }, []);

  useUpdateEffect(() => {
    if (props?.onSelectedRowsChange) {
      props.onSelectedRowsChange(selectedRows);
    }
  }, [selectedRows]);

  useUpdateEffect(() => {
    if (props?.multiple !== true) {
      setSelectedRows([]);
    }
  }, [props.multiple]);

  const request = (page, callback) => {
    if (props?.request) {
      setLoading(true);
      props
        .request?.(page ?? { pageNo, pageSize })
        .then(({ data, success, total }) => {
          if (success) {
            setDataList(data);
            setTotal(total || 0);
          }
          setLoading(false);
          callback?.();
        })
        .catch(() => {
          setLoading(false);
        });
    }
  };

  // 分页
  const getPagination = useMemo(() => {
    return (
      <Pagination
        align="end"
        pageSize={pageSize}
        current={pageNo}
        total={total}
        showQuickJumper
        hideOnSinglePage
        showTotal={(total, range) => {
          return `当前页 ${range[0]}-${range[1]} 条/共 ${total} 条`;
        }}
        pageSizeOptions={[`${pageSize}`, `${pageSize * 2}`, `${pageSize * 5}`, `${pageSize * 10}`]}
        onChange={(pageNo, pageSize) => {
          setPageNo(pageNo);
          setPageSize(pageSize);
          request({
            pageNo,
            pageSize
          });
        }}
      />
    );
  }, [pageNo, pageSize, total]);

  function findSelectedRowStatus(data) {
    return selectedRows.findIndex((item) => item[props?.rowKey] === data[props?.rowKey]) !== -1;
  }

  function onSelectedRows(data) {
    if (props.multiple) {
      setSelectedRows((prev) => {
        const index = prev.findIndex((item) => item[props?.rowKey] === data[props?.rowKey]);
        if (index === -1) {
          return [...prev, data];
        } else {
          return selectedRows.filter((item) => item[props?.rowKey] !== data[props?.rowKey]);
        }
      });
    }
  }

  return (
    <Flex vertical gap={SPACE}>
      <ListView
        loading={loading}
        pagination={false}
        grid={{
          gutter: [SPACE, SPACE],
          column: props.column,
          ...props.grid
        }}
        split={false}
        dataSource={dataList}
        locale={{ emptyText: '暂无数据' }}
        renderItem={(data, index) => {
          const isSelected = findSelectedRowStatus(data);
          const cardComponent = (
            <Card
              style={{
                height: '100%',
                cursor: isSelected ? 'not-allowed' : props.onClickCard ? 'pointer' : '',
                border: isSelected ? '1px solid var(--ant-color-primary)' : ''
              }}
              hoverable={props.multiple ? false : props.hoverable}
              styles={{
                body: {
                  padding: 0,
                  height: '100%'
                }
              }}
              onClick={() => {
                if (isSelected) {
                } else {
                  props.onClickCard && props.onClickCard(data);
                }
              }}
            >
              {props.multiple && (
                <MultipleIcon
                  className="card-list-multiple-icon"
                  selected={isSelected}
                  onClick={(e) => {
                    e.stopPropagation();
                    onSelectedRows(data);
                  }}
                >
                  <CheckCircleOutlined />
                </MultipleIcon>
              )}
              {props.renderItem(data, index)}
            </Card>
          );
          return (
            <List.Item className="card-list-item" style={{ marginBlockEnd: 0, height: '100%' }}>
              {props?.addCardBox != null ? props.addCardBox(data, cardComponent) : cardComponent}
            </List.Item>
          );
        }}
      />
      {getPagination}
    </Flex>
  );
});

export default CardList;
